<!DOCTYPE html>
<html lang="en">
  <head>
    <title>
        Java-framework-SpringBoot-5 - rulerLwx Blog
      </title>
        <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="format-detection" content="telephone=no,email=no,adress=no">
    
    <meta name="theme-color" content="#000000" />
    
    <meta http-equiv="window-target" content="_top" />
    
    
    <meta name="description" content="集成示例参考 https://github.com/xkcoding/spring-boot-demo Spring Boot &#43; MyBatis Mybatis和Spring Boot的整合有两种方式： 第一种：使用mybatis官方提供的Spring Boot整合包实" />
    <meta name="generator" content="Hugo 0.73.0 with theme pure" />
    <title>Java-framework-SpringBoot-5 - rulerLwx Blog</title>
    
    
    <link rel="stylesheet" href="https://rulerLwx.gitee.io/css/style.min.c4bc7071f132c964c2116bca53b392933f377e5ca7b7051ed245187c621a2d3e.css">
    
    <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/9.15.10/styles/github.min.css" async>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.css" async>
    <meta property="og:title" content="Java-framework-SpringBoot-5" />
<meta property="og:description" content="集成示例参考 https://github.com/xkcoding/spring-boot-demo Spring Boot &#43; MyBatis Mybatis和Spring Boot的整合有两种方式： 第一种：使用mybatis官方提供的Spring Boot整合包实" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://rulerLwx.gitee.io/2019/08/java-framework-springboot-5/" />
<meta property="article:published_time" content="2019-08-20T11:15:30+08:00" />
<meta property="article:modified_time" content="2019-08-20T11:15:30+08:00" />
<meta itemprop="name" content="Java-framework-SpringBoot-5">
<meta itemprop="description" content="集成示例参考 https://github.com/xkcoding/spring-boot-demo Spring Boot &#43; MyBatis Mybatis和Spring Boot的整合有两种方式： 第一种：使用mybatis官方提供的Spring Boot整合包实">
<meta itemprop="datePublished" content="2019-08-20T11:15:30&#43;08:00" />
<meta itemprop="dateModified" content="2019-08-20T11:15:30&#43;08:00" />
<meta itemprop="wordCount" content="5837">



<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Java-framework-SpringBoot-5"/>
<meta name="twitter:description" content="集成示例参考 https://github.com/xkcoding/spring-boot-demo Spring Boot &#43; MyBatis Mybatis和Spring Boot的整合有两种方式： 第一种：使用mybatis官方提供的Spring Boot整合包实"/>

    <!--[if lte IE 9]>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20170427/classList.min.js"></script>
      <![endif]-->

    <!--[if lt IE 9]>
        <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
      <![endif]-->
  </head>

  
  

  <body class="main-center theme-black" itemscope itemtype="http://schema.org/WebPage"><header class="header" itemscope itemtype="http://schema.org/WPHeader">
    <div class="slimContent">
      <div class="navbar-header">
        <div class="profile-block text-center">
          <a id="avatar" href="https://gitee.com/rulerLwx" target="_blank">
            <img class="img-circle img-rotate" src="https://rulerLwx.gitee.io/avatar.png" width="200" height="200">
          </a>
          <h2 id="name" class="hidden-xs hidden-sm">rulerLwx</h2>
          <h3 id="title" class="hidden-xs hidden-sm hidden-md">thinking...</h3>
          <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i>Guangzhou, China</small>
        </div><div class="search" id="search-form-wrap">
    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="Search" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i
                        class="icon icon-search"></i></button>
            </span>
        </div>
        <div class="ins-search">
            <div class="ins-search-mask"></div>
            <div class="ins-search-container">
                <div class="ins-input-wrapper">
                    <input type="text" class="ins-search-input" placeholder="Type something..."
                        x-webkit-speech />
                    <button type="button" class="close ins-close ins-selectable" data-dismiss="modal"
                        aria-label="Close"><span aria-hidden="true">×</span></button>
                </div>
                <div class="ins-section-wrapper">
                    <div class="ins-section-container"></div>
                </div>
            </div>
        </div>
    </form>
</div>
        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
      </div>
      <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
        <ul class="nav navbar-nav main-nav">
            <li class="menu-item menu-item-home">
                <a href="/">
                    <i class="icon icon-home-fill"></i>
                  <span class="menu-title">Home</span>
                </a>
            </li>
            <li class="menu-item menu-item-archives">
                <a href="/posts/">
                    <i class="icon icon-archives-fill"></i>
                  <span class="menu-title">Archives</span>
                </a>
            </li>
            <li class="menu-item menu-item-categories">
                <a href="/categories/">
                    <i class="icon icon-folder"></i>
                  <span class="menu-title">Categories</span>
                </a>
            </li>
            <li class="menu-item menu-item-tags">
                <a href="/tags/">
                    <i class="icon icon-tags"></i>
                  <span class="menu-title">Tags</span>
                </a>
            </li>
            <li class="menu-item menu-item-about">
                <a href="/about/">
                    <i class="icon icon-cup-fill"></i>
                  <span class="menu-title">About</span>
                </a>
            </li>
        </ul>
      </nav>
    </div>
  </header>

<aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">Board</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">enjoy~
            </div>
        </div>
    </div>
</div>

      <div class="widget">
    <h3 class="widget-title"> Categories</h3>
    <div class="widget-body">
        <ul class="category-list">
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-framework/" class="category-list-link">java-framework</a><span class="category-list-count">38</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-front-end/" class="category-list-link">java-front-end</a><span class="category-list-count">11</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-se/" class="category-list-link">java-se</a><span class="category-list-count">21</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-senior/" class="category-list-link">java-senior</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/linux/" class="category-list-link">linux</a><span class="category-list-count">13</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/tools/" class="category-list-link">tools</a><span class="category-list-count">1</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%8A%80%E6%9C%AF%E6%9D%82%E7%83%A9/" class="category-list-link">技术杂烩</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/" class="category-list-link">数据库</a><span class="category-list-count">15</span></li>
        </ul>
    </div>
</div>
      <div class="widget">
    <h3 class="widget-title"> Tags</h3>
    <div class="widget-body">
        <ul class="tag-list">
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/jvm/" class="tag-list-link">jvm</a><span
                    class="tag-list-count">1</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" class="tag-list-link">多线程</a><span
                    class="tag-list-count">2</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/" class="tag-list-link">网络编程</a><span
                    class="tag-list-count">3</span></li>
            
        </ul>

    </div>
</div>
      
<div class="widget">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget-body">
        <ul class="recent-post-list list-unstyled no-thumbnail">
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%87%AA%E5%B7%B1%E5%8A%A8%E6%89%8B%E4%B8%80%E6%89%B9%E9%87%8F%E7%A7%BB%E5%8A%A8%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6/" class="title">自己动手（一）——批量移动、重命名文件</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-27 17:50:02 &#43;0800 CST" itemprop="datePublished">2020-07-27</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E5%85%B3%E4%BA%8Einteger%E7%9A%84-128~127%E7%BC%93%E5%AD%98/" class="title">关于Integer的 -128~127缓存</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-11 16:56:21 &#43;0800 CST" itemprop="datePublished">2020-07-11</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/" class="title">跨域问题</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-08 22:41:12 &#43;0800 CST" itemprop="datePublished">2020-07-08</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/" class="title">个人博客搭建</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-05 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-05</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/mongodb-1/" class="title">MonggoDB-1</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-03 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-03</time>
                    </p>
                </div>
            </li>
        </ul>
    </div>
</div>
  </div>
</aside>

    
    
<aside class="sidebar sidebar-toc collapse" id="collapseToc" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    <h4 class="toc-title">Catalogue</h4>
    <nav id="toc" class="js-toc toc">

    </nav>
  </div>
</aside>
<main class="main" role="main"><div class="content">
  <article id="-" class="article article-type-" itemscope
    itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      <h1 itemprop="name">
  <a
    class="article-title"
    href="/2019/08/java-framework-springboot-5/"
    >Java-framework-SpringBoot-5</a
  >
</h1>

      <div class="article-meta">
        
<span class="article-date">
  <i class="icon icon-calendar-check"></i>&nbsp;
<a href="https://rulerLwx.gitee.io/2019/08/java-framework-springboot-5/" class="article-date">
  <time datetime="2019-08-20 11:15:30 &#43;0800 CST" itemprop="datePublished">2019-08-20</time>
</a>
</span>
<span class="article-category">
  <i class="icon icon-folder"></i>&nbsp;
  <a class="article-category-link" href="/categories/java-framework/"> Java-framework </a>
</span>

        <span class="post-comment"><i class="icon icon-comment"></i>&nbsp;<a href="/2019/08/java-framework-springboot-5/#comments"
            class="article-comment-link">Comments</a></span>
		<span class="post-wordcount hidden-xs" itemprop="wordCount">Word Count: 5837words</span>
		<span class="post-readcount hidden-xs" itemprop="timeRequired">Read Count: 12minutes </span>
      </div>
    </div>
    <div class="article-entry marked-body js-toc-content" itemprop="articleBody">
      <h1 id="集成示例参考">集成示例参考</h1>
<p><a href="https://github.com/xkcoding/spring-boot-demo">https://github.com/xkcoding/spring-boot-demo</a></p>
<h1 id="spring-boot--mybatis">Spring Boot + MyBatis</h1>
<p>Mybatis和Spring Boot的整合有两种方式：</p>
<ul>
<li>
<p>第一种：使用mybatis官方提供的Spring Boot整合包实现，地址：https://github.com/mybatis/spring-boot-starter</p>
<p>分为零配置（全注解）方式、xml方式。</p>
<p>可以参考官方示例：https://github.com/mybatis/spring-boot-starter/tree/master/mybatis-spring-boot-samples</p>
</li>
<li>
<p>第二种：使用mybatis-spring整合的方式，也就是我们传统的方式</p>
<p>这种可以很方便的控制Mybatis的各种配置。——我现在不是这么想，20190625</p>
</li>
</ul>
<h2 id="第一种使用mybatis官方提供的-mybatis-spring-boot-starter">第一种：使用mybatis官方提供的 mybatis-spring-boot-starter</h2>
<h3 id="零配置方式">零配置方式</h3>
<p>添加依赖</p>
<pre><code class="language-xml">    &lt;dependency&gt;
        &lt;groupId&gt;org.mybatis.spring.boot&lt;/groupId&gt;
        &lt;artifactId&gt;mybatis-spring-boot-starter&lt;/artifactId&gt;
        &lt;version&gt;2.0.0&lt;/version&gt;
    &lt;/dependency&gt;
</code></pre>
<p>书写Dao（Mapper接口）</p>
<pre><code class="language-java">@Mapper //要求Mybatis版本3.3及以上
public interface IUserMapper {
    @Select(&quot;select * from user where username like '%${value}%'&quot;)
    public List&lt;User&gt; findUserByName(String name);
}
</code></pre>
<p>然后，就是controller/service/dao之间的调用了</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708101018.png" alt=""></p>
<p>这里最大的不同点是在mapper接口的方法上使用注解写sql</p>
<hr>
<p>以下是mybatis零配置方式mapper接口方法的注解知识点</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708101035.png" alt=""></p>
<h3 id="xml写mapperxml方式">xml（写mapper.xml）方式</h3>
<p>1）在application.properties配置mybatis：</p>
<pre><code class="language-properties">mybatis.config-location=classpath:mybatis-conf.xml
mybatis.mapper-locations=classpath:mappers/*/*.xml
mybatis.type-aliases-package=com.demo.pojo
</code></pre>
<p>2）使用@Mapper注解mapper接口</p>
<pre><code class="language-java">@Mapper
public interface IUserMapper {
    public List&lt;User&gt; findUserByName(String name);
}
</code></pre>
<p>mapper.xml中的namespace与对应接口全类名一致、方法名一致。</p>
<h2 id="第二种使用传统-mybatis-spring-整合的方式">第二种：：使用传统 mybatis-spring 整合的方式</h2>
<p>首先创建一个Mybatis的配置类MyBatisConfig：</p>
<pre><code class="language-java">import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

@Configuration
public class MyBatisConfig {

    @Bean
    @ConditionalOnMissingBean //当容器里没有指定的Bean的情况下创建该对象
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 设置数据源
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 设置mybatis的主配置文件
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource mybatisConfigXml = resolver.getResource(&quot;classpath:mybatis/mybatis-config.xml&quot;);
        sqlSessionFactoryBean.setConfigLocation(mybatisConfigXml);
        // 设置别名包
        sqlSessionFactoryBean.setTypeAliasesPackage(&quot;com.taotao.cart.pojo&quot;);
        return sqlSessionFactoryBean;
    }
}
</code></pre>
<p>然后，创建Mapper接口的扫描类MapperScannerConfig</p>
<pre><code class="language-java">import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@AutoConfigureAfter(MyBatisConfig.class) //保证在MyBatisConfig实例化之后再实例化该类
public class MapperScannerConfig {
    
    // mapper接口的扫描器
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage(&quot;com.taotao.cart.mapper&quot;);
        return mapperScannerConfigurer;
    }
}
</code></pre>
<p>上面的两个配置相当于以前使用xml整合时spring配置文件application.xml中的两个&lt;bean&hellip;&gt;配置</p>
<p><img src="https://oscimg.oschina.net/oscnet/3309a88d75841b64f1f5e1aa28d41a88771.jpg" alt=""></p>
<p>此时整合使用的mybatis依赖是：</p>
<pre><code class="language-xml">	&lt;!-- Mybatis --&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.mybatis&lt;/groupId&gt;
		&lt;artifactId&gt;mybatis&lt;/artifactId&gt;
		&lt;version&gt;3.2.8&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.mybatis&lt;/groupId&gt;
		&lt;artifactId&gt;mybatis-spring&lt;/artifactId&gt;
		&lt;version&gt;1.2.2&lt;/version&gt;
	&lt;/dependency&gt;
</code></pre>
<h1 id="spring-boot--jpa">Spring Boot + JPA</h1>
<p>1）导入依赖</p>
<pre><code class="language-xml">    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
    &lt;/dependency&gt;
</code></pre>
<p>这个依赖自动导入了整合 JPA 所需要的所有包（抽象包、实现包），</p>
<p>包括 hibernate-core/hibernate-entitymanager 两个包，结合《Java-framework-Spring-Data-JPA》比较，更简洁了。</p>
<p>2）配置文件</p>
<p>Spring Boot + JPA 的配置文件只有一个：src/main/resources/application.properties</p>
<pre><code class="language-properties">spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
</code></pre>
<p>跟《Java-framework-Spring-Data-JPA》相比，不需要 spring-jpa.xml 配置文件，或 spring-jpa.xml 对应的“零配置”。</p>
<p>3）写接口、实体类、测试</p>
<p>跟《Java-framework-Spring-Data-JPA》完全相同</p>
<p>参考自己的代码：https://github.com/wolf-lea/spring-boot-v1520-demo/tree/master/22-spring-boot-jpa</p>
<h1 id="spring-boot--ehcache">Spring Boot + Ehcache</h1>
<p>1）依赖</p>
<pre><code class="language-xml">    &lt;!-- Spring Boot缓存支持启动器 --&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-cache&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;!-- Ehcache坐标 --&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;net.sf.ehcache&lt;/groupId&gt;
        &lt;artifactId&gt;ehcache&lt;/artifactId&gt;
    &lt;/dependency&gt;
</code></pre>
<p>2）Ehcache 配置文件 src/main/resources/ehcache.xml</p>
<p>如何配置这个文件？在 ehcache 的 Jar 包里有最简的配置：ehcache-2.10.5.jar!/ehcache-failsafe.xml</p>
<p>下面是示例配置</p>
<pre><code class="language-xml">&lt;ehcache xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:noNamespaceSchemaLocation=&quot;../config/ehcache.xsd&quot;&gt;

    &lt;diskStore path=&quot;java.io.tmpdir&quot;/&gt;

  &lt;!--defaultCache:echcache的默认缓存策略  --&gt;
    &lt;defaultCache
            maxElementsInMemory=&quot;10000&quot;
            eternal=&quot;false&quot;
            timeToIdleSeconds=&quot;120&quot;
            timeToLiveSeconds=&quot;120&quot;
            maxElementsOnDisk=&quot;10000000&quot;
            diskExpiryThreadIntervalSeconds=&quot;120&quot;
            memoryStoreEvictionPolicy=&quot;LRU&quot;&gt;
        &lt;persistence strategy=&quot;localTempSwap&quot;/&gt;
    &lt;/defaultCache&gt;
    &lt;!-- 自定义缓存策略 --&gt;
    &lt;cache name=&quot;users&quot;
            maxElementsInMemory=&quot;10000&quot;
            eternal=&quot;false&quot;
            timeToIdleSeconds=&quot;120&quot;
            timeToLiveSeconds=&quot;120&quot;
            maxElementsOnDisk=&quot;10000000&quot;
            diskExpiryThreadIntervalSeconds=&quot;120&quot;
            memoryStoreEvictionPolicy=&quot;LRU&quot;&gt;
        &lt;persistence strategy=&quot;localTempSwap&quot;/&gt;
    &lt;/cache&gt;
&lt;/ehcache&gt;
</code></pre>
<p>3）修改 application.properties</p>
<p>指定 ehcache 的配置文件位置</p>
<pre><code class="language-properties">spring.cache.ehcache.cofnig=ehcache.xml
</code></pre>
<p>4）在启动类上添加一个 @EnableCaching 注解</p>
<pre><code class="language-java">@SpringBootApplication
@EnableCaching
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}
</code></pre>
<p>5）使用 Ehcache 注解</p>
<p>ehcache没有学，TODO&hellip;</p>
<pre><code>
</code></pre>
<h1 id="spring-boot--redis">Spring Boot + Redis</h1>
<h2 id="旧方式-jedispoolconfig--jedispool-方式">旧方式-JedisPoolConfig + JedisPool 方式</h2>
<p>依赖：</p>
<pre><code class="language-xml">        &lt;dependency&gt;
            &lt;groupId&gt;redis.clients&lt;/groupId&gt;
            &lt;artifactId&gt;jedis&lt;/artifactId&gt;
            &lt;version&gt;2.6.2&lt;/version&gt;
        &lt;/dependency&gt;
</code></pre>
<p>配置类：</p>
<pre><code class="language-java">import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedisPool;

@Configuration
@PropertySource(value = &quot;classpath:redis.properties&quot;)
public class RedisSpringConfig {

    @Value(&quot;${redis.maxTotal}&quot;)
    private Integer redisMaxTotal;

    @Value(&quot;${redis.node1.host}&quot;)
    private String redisNode1Host;

    @Value(&quot;${redis.node1.port}&quot;)
    private Integer redisNode1Port;

    private JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(redisMaxTotal);
        return jedisPoolConfig;
    }

    @Bean
    public ShardedJedisPool shardedJedisPool() {
        List&lt;JedisShardInfo&gt; jedisShardInfos = new ArrayList&lt;JedisShardInfo&gt;();
        jedisShardInfos.add(new JedisShardInfo(redisNode1Host, redisNode1Port));
        return new ShardedJedisPool(jedisPoolConfig(), jedisShardInfos);
    }
}
</code></pre>
<p>调用：</p>
<pre><code class="language-java">    @Autowired
    ShardedJedisPool jedisPool;
    
    @GetMapping(&quot;/testRedis&quot;)
    public String testRedis(){
        ShardedJedis jedis = jedisPool.getResource();
        jedis.set(&quot;testRedis&quot;, &quot;testRedis-1&quot;);
        String testRedis = jedis.get(&quot;testRedis&quot;);
        System.out.println(&quot;----------&quot;+testRedis+&quot;===========&quot;);
        return testRedis;
    }
</code></pre>
<h2 id="spring-data-redis-方式">Spring Data Redis 方式</h2>
<p>结合《Java-framework-Spring-Data-Redis》一起思考</p>
<p>1）依赖</p>
<pre><code class="language-xml">    &lt;dependencies&gt;
        &lt;!-- Spring Data Redis的启动器 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-data-redis&lt;/artifactId&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
</code></pre>
<p>自动导入了 jedis 依赖，不需要另外导入。</p>
<p>2）application.properties</p>
<pre><code class="language-properties">spring.redis.pool.max-idle=10
spring.redis.pool.min-idle=5
spring.redis.pool.max-total=20

spring.redis.hostName=192.168.12.132
spring.redis.port=6379
</code></pre>
<p>3）redis 的 Java 配置（“零配置”）</p>
<pre><code class="language-java">@Configuration
public class RedisConfig {

	/**
	 * 1.创建JedisPoolConfig对象。在该对象中完成一些链接池配置
	 * @ConfigurationProperties:会将前缀相同的内容创建一个实体。
	 */
	@Bean
	@ConfigurationProperties(prefix=&quot;spring.redis.pool&quot;)
	public JedisPoolConfig jedisPoolConfig(){
		JedisPoolConfig config = new JedisPoolConfig();
		/*//最大空闲数
		config.setMaxIdle(10);
		//最小空闲数
		config.setMinIdle(5);
		//最大链接数
		config.setMaxTotal(20);*/
		System.out.println(&quot;默认值：&quot;+config.getMaxIdle());
		System.out.println(&quot;默认值：&quot;+config.getMinIdle());
		System.out.println(&quot;默认值：&quot;+config.getMaxTotal());
		return config;
	}
	
	/**
	 * 2.创建JedisConnectionFactory：配置redis链接信息
	 */
	@Bean
	@ConfigurationProperties(prefix=&quot;spring.redis&quot;)
	public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig config){
		System.out.println(&quot;配置完毕：&quot;+config.getMaxIdle());
		System.out.println(&quot;配置完毕：&quot;+config.getMinIdle());
		System.out.println(&quot;配置完毕：&quot;+config.getMaxTotal());
		
		JedisConnectionFactory factory = new JedisConnectionFactory();
		//关联链接池的配置对象
		factory.setPoolConfig(config);
		//配置链接Redis的信息
		//主机地址
		/*factory.setHostName(&quot;192.168.70.128&quot;);
		//端口
		factory.setPort(6379);*/
		return factory;
	}
	
	/**
	 * 3.创建RedisTemplate:用于执行Redis操作的方法
	 */
	@Bean
	public RedisTemplate&lt;String,Object&gt; redisTemplate(JedisConnectionFactory factory){
		RedisTemplate&lt;String, Object&gt; template = new RedisTemplate&lt;&gt;();
		//关联
		template.setConnectionFactory(factory);
		
		//为key设置序列化器
		template.setKeySerializer(new StringRedisSerializer());
		//为value设置序列化器
		template.setValueSerializer(new StringRedisSerializer());
		
		return template;
	}
}
</code></pre>
<p>疑问：为什么 redis 需要写 spring-redis.xml（转换为零配置）？而 mybatis/jpa 却不用写 spring-mybatis/jpa.xml ？</p>
<p>Spring Data Redis提供了两个模板：</p>
<ul>
<li>RedisTemplate</li>
<li>StringRedisTemplate</li>
</ul>
<h1 id="spring-boot--httpclient">Spring Boot + HttpClient</h1>
<p>依赖：</p>
<pre><code class="language-xml">		&lt;!-- httpclient --&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.apache.httpcomponents&lt;/groupId&gt;
			&lt;artifactId&gt;httpclient&lt;/artifactId&gt;
		&lt;/dependency&gt;
</code></pre>
<p>配置文件：</p>
<pre><code class="language-java">import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;

import com.taotao.common.httpclient.IdleConnectionEvictor;

@Configuration
@PropertySource(value = &quot;classpath:httpclient.properties&quot;)
public class HttpclientSpringConfig {

    @Value(&quot;${http.maxTotal}&quot;)
    private Integer httpMaxTotal;

    @Value(&quot;${http.defaultMaxPerRoute}&quot;)
    private Integer httpDefaultMaxPerRoute;

    @Value(&quot;${http.connectTimeout}&quot;)
    private Integer httpConnectTimeout;

    @Value(&quot;${http.connectionRequestTimeout}&quot;)
    private Integer httpConnectionRequestTimeout;

    @Value(&quot;${http.socketTimeout}&quot;)
    private Integer httpSocketTimeout;

    @Value(&quot;${http.staleConnectionCheckEnabled}&quot;)
    private Boolean httpStaleConnectionCheckEnabled;

    @Autowired
    private PoolingHttpClientConnectionManager manager;

    @Bean
    public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        poolingHttpClientConnectionManager.setMaxTotal(httpMaxTotal);
        // 每个主机的最大并发数
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(httpDefaultMaxPerRoute);
        return poolingHttpClientConnectionManager;
    }

    // 定期关闭无效连接
    @Bean
    public IdleConnectionEvictor idleConnectionEvictor() {
        return new IdleConnectionEvictor(manager);
    }

    // 定义Httpclient对
    @Bean
    @Scope(&quot;prototype&quot;)
    public CloseableHttpClient closeableHttpClient() {
        return HttpClients.custom().setConnectionManager(this.manager).build();
    }

    // 请求配置
    @Bean
    public RequestConfig requestConfig() {
        return RequestConfig.custom().setConnectTimeout(httpConnectTimeout) // 创建连接的最长时间
                .setConnectionRequestTimeout(httpConnectionRequestTimeout) // 从连接池中获取到连接的最长时间
                .setSocketTimeout(httpSocketTimeout) // 数据传输的最长时间
                .setStaleConnectionCheckEnabled(httpStaleConnectionCheckEnabled) // 提交请求前测试连接是否可用
                .build();
    }

}
</code></pre>
<h1 id="spring-boot--rabbitmq">Spring Boot + RabbitMQ</h1>
<h1 id="spring-boot--servletfilterlistener">Spring Boot + Servlet/Filter/Listener</h1>
<p>需要在启动类中添加一个 @ServletComponetScan 注解，其它的零配置跟《Java-Se-Servlet》一致。</p>
<pre><code class="language-java">@SpringBootApplication
@ServletComponentScan
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class);
    }
}

</code></pre>
<h1 id="spring-boot--jsp">Spring Boot + JSP</h1>
<pre><code class="language-xml">	&lt;dependency&gt;
		&lt;groupId&gt;javax.servlet&lt;/groupId&gt;
		&lt;artifactId&gt;jstl&lt;/artifactId&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.apache.tomcat.embed&lt;/groupId&gt;
		&lt;artifactId&gt;tomcat-embed-jasper&lt;/artifactId&gt;
		&lt;scope&gt;provided&lt;/scope&gt;
	&lt;/dependency&gt;
</code></pre>
<p>参考官方示例：https://github.com/spring-projects/spring-boot/tree/v1.5.20.RELEASE/spring-boot-samples/spring-boot-sample-web-jsp</p>
<h1 id="spring-boot--freemarkthymeleaf">Spring Boot + FreeMark/Thymeleaf</h1>
<p>文件必须放在 src\main\resources\templates 下，文件夹名称必须是 templates</p>
<p>因为Spring Boot通过 <code>org.springframework.boot.autoconfigure.freemarker</code>包对 freemark进行了自动化设置</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708101155.png" alt=""></p>
<p>查看 <code>FreeMarkerProperties</code> 类就可以看到 <code>DEFAULT_TEMPLATE_LOADER_PATH = &quot;classpath:/templates/&quot;</code> 配置。thymeleaf同理。</p>
<p>templates目录是安全的，外界不能直接访问该目录下的文件；</p>
<p>Controller中返回的视图名称跟静态页面名称一致</p>
<h1 id="定时任务">定时任务</h1>
<p>有两种方式实现定时任务</p>
<ul>
<li>Scheduled 定时任务器</li>
<li>整合Quartz 定时任务框架</li>
</ul>
<h2 id="scheduled">Scheduled</h2>
<p>Scheduled 是 Spring 3.0以后自带的一个定时任务器。</p>
<p>1）依赖</p>
<pre><code class="language-xml">    &lt;dependencies&gt;
        &lt;!-- 添加Scheduled坐标 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework&lt;/groupId&gt;
            &lt;artifactId&gt;spring-context-support&lt;/artifactId&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
</code></pre>
<p>2）编写定时任务类</p>
<pre><code class="language-java">@Component
public class ScheduledDemo {

	/**
	 * 定时任务方法
	 * @Scheduled:设置定时任务
	 * cron属性：cron表达式。定时任务触发是时间的一个字符串表达形式
	 */
	@Scheduled(cron=&quot;0/2 * * * * ?&quot;)
	public void scheduledMethod(){
		System.out.println(&quot;定时器被触发&quot;+new Date());
	}
}
</code></pre>
<p>3）在启动类中开启定时任务的使用</p>
<pre><code class="language-java">@SpringBootApplication
@EnableScheduling
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}
</code></pre>
<p>cron 表达式讲解：</p>
<p>Cron 表达式是一个字符串，分为6 或7 个域，每一个域代表一个含义</p>
<p>Cron 有如下两种语法格式：</p>
<ul>
<li>（1） Seconds Minutes Hours Day Month Week Year</li>
<li>（2）Seconds Minutes Hours Day Month Week</li>
</ul>
<p>1）结构</p>
<p>corn 从左到右（用空格隔开）：秒 分 小时 月份中的日期 月份 星期中的日期 年份</p>
<p>2）各字段的含义</p>
<table>
<thead>
<tr>
<th>位置</th>
<th>时间域名</th>
<th>允许值</th>
<th>允许的特殊字符</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>秒</td>
<td>0-59</td>
<td>, - * /</td>
</tr>
<tr>
<td>2</td>
<td>分钟</td>
<td>0-59</td>
<td>, - * /</td>
</tr>
<tr>
<td>3</td>
<td>小时</td>
<td>0-23</td>
<td>, - * /</td>
</tr>
<tr>
<td>4</td>
<td>日</td>
<td>1-31</td>
<td>, - * / L W C</td>
</tr>
<tr>
<td>5</td>
<td>月</td>
<td>1-12</td>
<td>, - * /</td>
</tr>
<tr>
<td>6</td>
<td>星期</td>
<td>1-7</td>
<td>, - * ? / L C #</td>
</tr>
<tr>
<td>7</td>
<td>年(可选)</td>
<td>1970-2099</td>
<td>, - * /</td>
</tr>
</tbody>
</table>
<p>Cron 表达式的时间字段除允许设置数值外，还可使用一些特殊的字符，提供列表、范围、通配符等功能，细说如下：</p>
<ul>
<li>星号(*)：可用在所有字段中，表示对应时间域的每一个时刻，例如，*在分钟字段时，表示“每分钟”；</li>
<li>问号（?）：该字符只在日期和星期字段中使用，它通常指定为“无意义的值”，相当于占位符；</li>
<li>减号(-)：表达一个范围，如在小时字段中使用“10-12”，则表示从10 到12 点，即10,11,12；</li>
<li>逗号(,)：表达一个列表值，如在星期字段中使用“MON,WED,FRI”，则表示星期一，星期三和星期五；</li>
<li>斜杠(/)：x/y 表达一个等步长序列，x 为起始值，y 为增量步长值。如在分钟字段中使用0/15，则表示为0,15,30 和45 秒，而5/15 在分钟字段中表示5,20,35,50，你也可以使用*/y，它等同于0/y；</li>
<li>L：该字符只在日期和星期字段中使用，代表“Last”的意思，但它在两个字段中意思不同。L 在日期字段中，表示这个月份的最后一天，如一月的31 号，非闰年二月的28 号；如果L 用在星期中，则表示星期六，等同于7。但是，如果L 出现在星期字段里，而且在前面有一个数值X，则表示“这个月的最后X 天”，例如，6L 表示该月的最后星期五；</li>
<li>W：该字符只能出现在日期字段里，是对前导日期的修饰，表示离该日期最近的工作日。例如15W
表示离该月15 号最近的工作日，如果该月15 号是星期六，则匹配14 号星期五；如果15 日是星期日，
则匹配16 号星期一；如果15 号是星期二，那结果就是15 号星期二。但必须注意关联的匹配日期不能够
跨月，如你指定1W，如果1 号是星期六，结果匹配的是3 号星期一，而非上个月最后的那天。W 字符串
只能指定单一日期，而不能指定日期范围；</li>
<li>LW 组合：在日期字段可以组合使用LW，它的意思是当月的最后一个工作日；</li>
<li>井号(#)：该字符只能在星期字段中使用，表示当月某个工作日。如6#3 表示当月的第三个星期五(6
表示星期五，#3 表示当前的第三个)，而4#5 表示当月的第五个星期三，假设当月没有第五个星期三，
忽略不触发；</li>
<li>C：该字符只在日期和星期字段中使用，代表“Calendar”的意思。它的意思是计划所关联的日期，
如果日期没有被关联，则相当于日历中所有日期。例如5C 在日期字段中就相当于日历5 日以后的第一天。
1C 在星期字段中相当于星期日后的第一天。</li>
</ul>
<p>Cron 表达式对特殊字符的大小写不敏感，对代表星期的缩写英文大小写也不敏感。</p>
<p>例子:</p>
<ul>
<li>@Scheduled(cron = &ldquo;0 0 1 1 1 ?&quot;) //每年一月的一号的1:00:00 执行一次</li>
<li>@Scheduled(cron = &ldquo;0 0 1 1 1,6 ?&quot;) //一月和六月的一号的1:00:00 执行一次</li>
<li>@Scheduled(cron = &ldquo;0 0 1 1 1,4,7,10 ?&quot;) //每个季度的第一个月的一号的1:00:00 执行一次</li>
<li>@Scheduled(cron = &ldquo;0 0 1 1 * ?&quot;) //每月一号1:00:00 执行一次</li>
<li>@Scheduled(cron=&quot;0 0 1 * * *&quot;) //每天凌晨1 点执行一次</li>
</ul>
<h2 id="quartz">Quartz</h2>
<h3 id="quartz入门">Quartz入门</h3>
<p>开源项目：https://github.com/quartz-scheduler/quartz</p>
<p>1）Quartz 的使用思路</p>
<ul>
<li>job - 任务- 你要做什么事？</li>
<li>Trigger - 触发器- 你什么时候去做？</li>
<li>Scheduler - 任务调度- 你什么时候需要去做什么事？</li>
</ul>
<p>对 JDK 版本要求：https://github.com/quartz-scheduler/quartz/wiki</p>
<p>使用2.2.x系列 —— 20190524</p>
<p>2）依赖</p>
<pre><code class="language-xml">    &lt;dependencies&gt;
        &lt;!-- Quartz坐标 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.quartz-scheduler&lt;/groupId&gt;
            &lt;artifactId&gt;quartz&lt;/artifactId&gt;
            &lt;version&gt;2.2.1&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
</code></pre>
<p>3）创建Job 类</p>
<pre><code class="language-java">public class QuartzDemo implements Job {

	/**
	 * 任务被触发时所执行的方法
	 */
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		System.out.println(&quot;Execute....&quot;+new Date());
	}
}
</code></pre>
<p>4）测试代码</p>
<pre><code class="language-java">public class QuartzMain {

	public static void main(String[] args) throws Exception {

		// 1.创建Job对象：你要做什么事？
		JobDetail job = JobBuilder.newJob(QuartzDemo.class).build();

		/**
		 * 简单的trigger触发时间：通过Quartz提供一个方法来完成简单的重复调用 cron
		 * Trigger：按照Cron的表达式来给定触发的时间
		 */
		// 2.创建Trigger对象：在什么时间做？
		/*Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever())
				.build();*/
		
		
		Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule(&quot;0/2 * * * * ?&quot;))
				.build();

		// 3.创建Scheduler对象：在什么时间做什么事？
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
		scheduler.scheduleJob(job, trigger);
		
		//启动
		scheduler.start();
	}
}
</code></pre>
<h3 id="spring-boot--quartz">Spring Boot + Quartz</h3>
<p>1）依赖</p>
<p>需要3个依赖</p>
<pre><code class="language-xml">    &lt;dependencies&gt;
        &lt;!-- Quartz坐标 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.quartz-scheduler&lt;/groupId&gt;
            &lt;artifactId&gt;quartz&lt;/artifactId&gt;
            &lt;version&gt;2.2.2&lt;/version&gt;
            &lt;exclusions&gt;
                &lt;exclusion&gt;
                    &lt;artifactId&gt;slf4j-api&lt;/artifactId&gt;
                    &lt;groupId&gt;org.slf4j&lt;/groupId&gt;
                &lt;/exclusion&gt;
            &lt;/exclusions&gt;
        &lt;/dependency&gt;

        &lt;!-- 添加Scheduled坐标 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework&lt;/groupId&gt;
            &lt;artifactId&gt;spring-context-support&lt;/artifactId&gt;
        &lt;/dependency&gt;

        &lt;!-- Sprng tx 坐标 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework&lt;/groupId&gt;
            &lt;artifactId&gt;spring-tx&lt;/artifactId&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
</code></pre>
<p>2）创建 Job 类</p>
<pre><code class="language-java">public class QuartzDemo implements Job {
	
	@Autowired
	private UsersService usersService;
	
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		System.out.println(&quot;Execute....&quot;+new Date());
		this.usersService.addUsers();
	}
}
</code></pre>
<p>3）为了在 QuartzDemo 在可以注入 Spring IOC 容器中的对象 usersService，需要编写一个 MyAdaptableJobFactory</p>
<pre><code class="language-java">@Component(&quot;myAdaptableJobFactory&quot;)
public class MyAdaptableJobFactory extends AdaptableJobFactory {

	//AutowireCapableBeanFactory 可以将一个对象添加到SpringIOC容器中，并且完成该对象注入
	@Autowired
	private AutowireCapableBeanFactory autowireCapableBeanFactory;
	
	/**
	 * 该方法需要将实例化的任务对象手动的添加到springIOC容器中并且完成对象的注入
	 */
	@Override
	protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
		Object obj = super.createJobInstance(bundle);
		//将obj对象添加Spring IOC容器中，并完成注入
		this.autowireCapableBeanFactory.autowireBean(obj);
		return obj;
	}
}
</code></pre>
<p>4）编写 quartz 配置类</p>
<pre><code class="language-java">@Configuration
public class QuartzConfig {

	
	/**
	 * 1.创建Job对象
	 */
	@Bean
	public JobDetailFactoryBean jobDetailFactoryBean(){
		JobDetailFactoryBean factory = new JobDetailFactoryBean();
		//关联我们自己的Job类
		factory.setJobClass(QuartzDemo.class);
		return factory;
	}
	
	/**
	 * 2.创建Trigger对象
	 * 简单的Trigger
	 */
	/*@Bean
	public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
		SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
		//关联JobDetail对象
		factory.setJobDetail(jobDetailFactoryBean.getObject());
		//该参数表示一个执行的毫秒数
		factory.setRepeatInterval(2000);
		//重复次数
		factory.setRepeatCount(5);
		return factory;
	}*/
	
	/**
	 * Cron Trigger
	 */
	@Bean
	public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
		CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
		factory.setJobDetail(jobDetailFactoryBean.getObject());
		//设置触发时间
		factory.setCronExpression(&quot;0/2 * * * * ?&quot;);
		return factory;
	}
	
	/**
	 * 3.创建Scheduler对象
	 */
	@Bean
	public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean,MyAdaptableJobFactory myAdaptableJobFactory){
		SchedulerFactoryBean factory = new SchedulerFactoryBean();
		//关联trigger
		factory.setTriggers(cronTriggerFactoryBean.getObject());
		factory.setJobFactory(myAdaptableJobFactory);
		return factory;
	}
}
</code></pre>
<p>5）启动类</p>
<pre><code class="language-java">@SpringBootApplication
@EnableScheduling
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}
</code></pre>
<p>代码：https://github.com/wolf-lea/spring-boot-v1520-demo/tree/master/27-spring-boot-quartz</p>
<h1 id="faq">FAQ</h1>
<h2 id="caused-by-javalangclassnotfoundexception-redisclientsjedisgeounit">Caused by: java.lang.ClassNotFoundException: redis.clients.jedis.GeoUnit</h2>
<p>Redis jar包冲突，新旧版同时在Maven中，解决办法：排除（移除）低版本的jar包。</p>
<p>参考 jar包冲突那些事，编译器不报错，启动报错： <a href="https://blog.csdn.net/li396864285/article/details/53290354">https://blog.csdn.net/li396864285/article/details/53290354</a></p>

    </div>
    <div class="article-footer">
<blockquote class="mt-2x">
  <ul class="post-copyright list-unstyled">
    <li class="post-copyright-link hidden-xs">
      <strong>Permalink: </strong>
      <a href="https://rulerLwx.gitee.io/2019/08/java-framework-springboot-5/" title="Java-framework-SpringBoot-5" target="_blank" rel="external">https://rulerLwx.gitee.io/2019/08/java-framework-springboot-5/</a>
    </li>
    <li class="post-copyright-license">
      <strong>License：</strong><a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN</a>
    </li>
  </ul>
</blockquote>

<div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="https://gitee.com/rulerLwx" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="https://rulerLwx.gitee.io/avatar.png" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="https://gitee.com/rulerLwx" target="_blank"><span class="text-dark">rulerLwx</span><small class="ml-1x">thinking...</small></a></h3>
        <div>Good Good Study, Day Day Up~</div>
      </div>
    </figure>
  </div>
</div>
    </div>
  </article>
<section id="comments">
    <div id="vcomments"></div>
</section>

</div><nav class="bar bar-footer clearfix" data-stick-bottom>
    <div class="bar-inner">
        <ul class="pager pull-left">
            <li class="prev">
                <a href="https://rulerLwx.gitee.io/2019/08/java-framework-springboot-4/" title="Java-framework-SpringBoot-4"><i
                        class="icon icon-angle-left"
                        aria-hidden="true"></i><span>&nbsp;&nbsp;Older</span></a>
            </li>
            <li class="next">
                <a href="https://rulerLwx.gitee.io/2019/08/java-framework-springboot-6-%E6%95%B4%E5%90%88-redis-%E5%93%A8%E5%85%B5-sentinel/"
                    title="Java-framework-SpringBoot-6-整合 Redis 哨兵 Sentinel"><span>Newer&nbsp;&nbsp;</span><i
                        class="icon icon-angle-right" aria-hidden="true"></i></a>
            </li>
            
            <li class="toggle-toc">
                <a class="toggle-btn collapsed" data-toggle="collapse" href="#collapseToc" aria-expanded="false"
                    title="Catalogue" role="button">
                    <span>[&nbsp;</span><span>Catalogue</span>
                    <i class="text-collapsed icon icon-anchor"></i>
                    <i class="text-in icon icon-close"></i>
                    <span>]</span>
                </a>
            </li>
        </ul>
        <div class="bar-right">
            <div class="share-component" data-sites="weibo,qq,wechat"
                data-mobile-sites="weibo,qq,qzone"></div>
        </div>
    </div>
</nav>

</main><footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
<ul class="social-links">
    <li><a href="https://gitee.com/rulerLwx" target="_blank" title="gitee" data-toggle=tooltip data-placement=top >
            <i class="icon icon-gitee"></i></a></li>
    <li><a href="https://github.com/wolf-lea" target="_blank" title="github" data-toggle=tooltip data-placement=top >
            <i class="icon icon-github"></i></a></li>
</ul>
  <div class="copyright">
    &copy;2017  -
    2020
    <div class="publishby">
        Theme by <a href="https://github.com/xiaoheiAh" target="_blank"> xiaoheiAh </a>base on<a href="https://github.com/xiaoheiAh/hugo-theme-pure" target="_blank"> pure</a>.
    </div>
  </div>
</footer>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_SVG"></script>
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
            showMathMenu: false, //disables context menu
            tex2jax: {
            inlineMath: [ ['$','$'], ['\\(','\\)'] ]
           }
    });
</script>


<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>
<script>
    window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/highlight.min.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/python.min.js" defer></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/javascript.min.js" defer></script><script>
    hljs.configure({
        tabReplace: '    ', 
        classPrefix: ''     
        
    })
    hljs.initHighlightingOnLoad();
</script>
<script src="https://rulerLwx.gitee.io/js/application.min.bdeb64b910570b6c41badc6a05b7afb0c8ad9efd8525de3c7257d59e786326a3.js"></script>
<script src="https://rulerLwx.gitee.io/js/plugin.min.51ff8c7317566f82259170fa36e09c4493adc9b9378b427a01ad3f017ebac7dd.js"></script>

<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: 'Posts',
                PAGES: 'Pages',
                CATEGORIES: 'Categories',
                TAGS: 'Tags',
                UNTITLED: '(Untitled)',
            },
            ROOT_URL: 'https:\/\/rulerLwx.gitee.io',
            CONTENT_URL: 'https:\/\/rulerLwx.gitee.io\/searchindex.json ',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>
<script type="text/javascript" src="https://rulerLwx.gitee.io/js/insight.min.a343cd9a5a7698336b28ef3a7c16a3a1b1d2d5fb17dc8ed04022bbe08cc5459073a15bdafa3a8a58cdd56080784bdd69fa70b1ae8597565c799c57ed00f0e120.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.min.js"></script>
<script>
    tocbot.init({
        
        tocSelector: '.js-toc',
        
        contentSelector: '.js-toc-content',
        
        headingSelector: 'h1, h2, h3',
        
        hasInnerContainers: true,
    });
</script>

<script src="https://cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/valine"></script>
<script type="text/javascript">
    var GUEST = ['nick', 'mail', 'link'];
    var meta = 'nick,mail';
    meta = meta.split(',').filter(function (item) {
        return GUEST.indexOf(item) > -1;
    });
    new Valine({
        el: '#vcomments',
        verify: null ,
        notify: null ,
        appId: 'IyAB0PSPRazTPDxitO1ddQ7O-gzGzoHsz',
        appKey: '5rBJTq4KidYF33eXwvRVhtEH',
        placeholder: 'enjoy~',
        avatar: 'mm',
        meta: meta,
        pageSize: '10' || 10,
        visitor: false 
});
</script>

  </body>
</html>
